package com.yanqu.road.server.cross3server.manager;

import com.yanqu.road.entity.activity.entername.ActivityGroupMatch;
import com.yanqu.road.entity.activity.entername.UserEnterName;
import com.yanqu.road.pb.cross3.activity.EnterNameProto;
import com.yanqu.road.server.TempMgr;
import com.yanqu.road.server.logic.MessageHelper;
import com.yanqu.road.server.protocol.ChannelProtocol;
import com.yanqu.road.utils.ConfigHelper;
import com.yanqu.road.utils.YanQuMessageUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class Cross3EnterNameMgr extends TempMgr {

    //activityId
    private static Map<Integer, Map<Long, UserEnterName>>  nameMap = new ConcurrentHashMap<>();

    //activityId
    private static Map<Integer, List<ActivityGroupMatch>> matchMap = new ConcurrentHashMap<>();

    //activityId
    private static volatile boolean dataSync = false;

    @Override
    public boolean init() throws Exception {
        return reload();
    }

    @Override
    public boolean reloadConfig() throws Exception {
        return true;
    }

    @Override
    public boolean reloadData() throws Exception {
        return true;
    }

    @Override
    public boolean stop() {
        return false;
    }

    public static void add(UserEnterName userEnterName){
        Map<Long, UserEnterName> map = nameMap.get(userEnterName.getActivityId());
        if(map == null){
            synchronized (nameMap){
                map = nameMap.get(userEnterName.getActivityId());
                if(map == null){
                    map = new ConcurrentHashMap<>();
                    nameMap.put(userEnterName.getActivityId(), map);
                }
            }
        }
        map.put(userEnterName.getUserId(), userEnterName);
    }

    public static void add(int activityId, Map<Long, UserEnterName> userEnterNameMap){
        Map<Long, UserEnterName> map = nameMap.get(activityId);
        if(map == null){
            synchronized (nameMap){
                map = nameMap.get(activityId);
                if(map == null){
                    map = new ConcurrentHashMap<>();
                    nameMap.put(activityId, map);
                }
            }
        }
        map.putAll(userEnterNameMap);
    }

    //上区域拉取本渠道报名信息
    public static void dataSync(){
        if(!dataSync){
            EnterNameProto.ChannelEnterNameAllSyncReqMsg.Builder messageBuilder = EnterNameProto.ChannelEnterNameAllSyncReqMsg.newBuilder().setActivityId(0);
            messageBuilder.setChannelId(ConfigHelper.getInt("channelId"));
            MessageHelper.sendChannelServer(YanQuMessageUtils.buildMessage(ChannelProtocol.N_ENTER_NAME_ALL_SYNC, messageBuilder));
        }
    }

    public static Map<Integer, Map<Long, UserEnterName>> getNameMap() {
        return nameMap;
    }

    public static void setNameMap(Map<Integer, Map<Long, UserEnterName>> nameMap) {
        Cross3EnterNameMgr.nameMap = nameMap;
    }

    public static void setActivityNameMap(int activityId, Map<Long, UserEnterName> nameMap){
        Cross3EnterNameMgr.nameMap.put(activityId, nameMap);
    }

    public static void setDataSync(boolean dataSync) {
        Cross3EnterNameMgr.dataSync = dataSync;
    }

    public static Map<Integer, List<ActivityGroupMatch>> getMatchMap() {
        return matchMap;
    }

    public static void setMatchMap(Map<Integer, List<ActivityGroupMatch>> matchMap) {
        Cross3EnterNameMgr.matchMap = matchMap;
    }

    public static int getUserEnterNameGroupId(int activityId, long userId){
        UserEnterName enterName = getUserEnterName(activityId, userId);
        if(enterName == null){
            return 0;
        }
        return getGroupId(activityId, enterName.getZoneId());
    }

    public static UserEnterName getUserEnterName(int activityId, long userId){
        Map<Long, UserEnterName> map = nameMap.get(activityId);
        if(map != null){
            return map.get(userId);
        }
        return null;
    }

    public static int getMatchGroupId(int activityId, long userId){
        UserEnterName userEnterName = getUserEnterName(activityId, userId);
        if(userEnterName != null){
            return getMatchGroupId(activityId, userEnterName.getZoneId());
        }
        return 0;
    }

    public static int getGroupId(int activityId, int zoneId){
        List<ActivityGroupMatch> list = matchMap.get(activityId);
        if(list != null){
            for (ActivityGroupMatch groupMatch : list) {
                if(groupMatch.getZoneIdList().contains(zoneId)){
                    return groupMatch.getGroupId();
                }
            }
        }
        return 0;
    }

    public static int getMatchGroupId(int activityId, int zoneId){
        List<ActivityGroupMatch> list = matchMap.get(activityId);
        if(list != null){
            for (ActivityGroupMatch groupMatch : list) {
                if(groupMatch.getZoneIdList().contains(zoneId)){
                    return groupMatch.getRankMatchGroupId();
                }
            }
        }
        return 0;
    }

    public static void updateUserGroup(int activityId) {
        Map<Long, UserEnterName> map = nameMap.get(activityId);
        if(map != null){
            for (Map.Entry<Long, UserEnterName> nameEntry : map.entrySet()) {
                UserEnterName userEnterName = nameEntry.getValue();
                if(userEnterName.getGroupId() == 0){
                    userEnterName.setGroupId(getGroupId(activityId, userEnterName.getZoneId()));
                }
            }
        }
    }

    public static Map<Long, List<UserEnterName>> getUserNameGroupByServer(int activityId){
        Map<Long, List<UserEnterName>> map = new HashMap<>();
        Map<Long, UserEnterName> userMap = nameMap.get(activityId);
        if(userMap != null) {
            for (Map.Entry<Long, UserEnterName> nameEntry : userMap.entrySet()) {
                UserEnterName userEnterName = nameEntry.getValue();
                if(!map.containsKey(userEnterName.getServerId())){
                    map.put(userEnterName.getServerId(), new ArrayList<>());
                }
                map.get(userEnterName.getServerId()).add(userEnterName);
            }
        }
        return map;
    }
}
